// ClientApp.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <winioctl.h>

/*
Self-Defined I/O Control Code
*/
//I/O Control Code for Device Information retrieval
#define IOCTL_READ_DEVICE_INFO	\
	CTL_CODE(					\
		 FILE_DEVICE_UNKNOWN,	\
		 0x800,					\
		 METHOD_BUFFERED,		\
		 FILE_ANY_ACCESS)

//I/O Control Code for Power Information retrieval
#define IOCTL_READ_POWER_INFO	\
	CTL_CODE(					\
		 FILE_DEVICE_UNKNOWN,	\
		 0x801,					\
		 METHOD_BUFFERED,		\
		 FILE_ANY_ACCESS)

/*
Device Power State Structure
*/
typedef struct tagDEVICE_POWER_INFORMATION {
  BOOLEAN   SupportQueryCapability;
  ULONG  DeviceD1;
  ULONG  DeviceD2;
  ULONG  WakeFromD0;
  ULONG  WakeFromD1;
  ULONG  WakeFromD2;
  ULONG  WakeFromD3;
  SYSTEM_POWER_STATE  SystemWake;
  DEVICE_POWER_STATE  DeviceWake;
  DEVICE_POWER_STATE  DeviceState[PowerSystemMaximum];
} DEVICE_POWER_INFORMATION, *PDEVICE_POWER_INFORMATION;

int main(int argc, char* argv[])
{
	HANDLE hdevice = CreateFile("\\\\.\\PSEUDODEVICE", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
	if (hdevice == INVALID_HANDLE_VALUE)
	{
		printf("Unable to open PSEUDODEVICE device - error %d\n", GetLastError());
		return 1;
	}

	wchar_t answer[512] = {'\0'};
	DWORD junk;
	if (DeviceIoControl(hdevice, IOCTL_READ_DEVICE_INFO, NULL, 0, answer, sizeof(answer), &junk, NULL))
	{
		answer[junk] = 0;
		//MessageBoxW(NULL,answer, NULL, 0);
		wprintf(L"%s",answer);
	}
	else
		printf("Error %d in call to DeviceIoControl\n", GetLastError());
	
	PDEVICE_POWER_INFORMATION ptr_PwrInfo;
	ptr_PwrInfo = (PDEVICE_POWER_INFORMATION)malloc(
		sizeof(DEVICE_POWER_INFORMATION));

	int IdxPwrState;
	if (DeviceIoControl(hdevice, IOCTL_READ_POWER_INFO, NULL, 0, ptr_PwrInfo, sizeof(DEVICE_POWER_INFORMATION), &junk, NULL))
	{
		printf("Support Query Device Capability : %s\r\n", (ptr_PwrInfo->SupportQueryCapability ? "Yes" : "No") );
		printf("DeviceD1 : %d\r\n", ptr_PwrInfo->DeviceD1);
		printf("DeviceD2 : %d\r\n", ptr_PwrInfo->DeviceD2);
		printf("WakeFromD0 : %d\r\n", ptr_PwrInfo->WakeFromD0);
		printf("WakeFromD1 : %d\r\n", ptr_PwrInfo->WakeFromD1);
		printf("WakeFromD2 : %d\r\n", ptr_PwrInfo->WakeFromD2);
		printf("WakeFromD3 : %d\r\n", ptr_PwrInfo->WakeFromD3);
		printf("SystemWake : %d\r\n", ptr_PwrInfo->SystemWake);
		printf("DeviceWake : %d\r\n", ptr_PwrInfo->DeviceWake);
		for (IdxPwrState = 0; 
			IdxPwrState < PowerSystemMaximum;
			IdxPwrState++)
		{
			printf("DeviceState[%d] : %d\r\n", 
				IdxPwrState, 
				ptr_PwrInfo->DeviceState[IdxPwrState]);

		}
	}
	else
		printf("Error %d in call to DeviceIoControl\n", GetLastError());


	CloseHandle(hdevice);
	return 0;
}

